#ifndef __CHUNCK_READER_H__
#define __CHUNCK_READER_H__

#include <vector>
#include <fstream>
using namespace std;

class CChunkFileReader;

#define DWORD unsigned long

class CChunkRead
{
	CChunkFileReader* m_pChunkFile;
	int  m_Offset;

	friend class CChunkFileReader;
	int  m_Len;
	int  _read(char* buf, int len);
public:
	CChunkRead();
	int  len(){return m_Len;}
	bool beginRead();
	bool endRead();

	

	template <typename T > int read(T& Data)
	{
		return _read( (char*)&Data,sizeof(T));
	}

	template <typename T > int read(T* Data,int nElement)
	{
		return _read( (char*)Data,sizeof(T)*nElement);
	}

	bool seek(int len , ios::seek_dir);
};


class CChunkWrite
{
	char* m_Buffer;
	int   m_Len;
	int   m_seekPos;
	int   m_DataLen;
	bool __alloc(int len);
	bool __release();
	friend class CChunkFileWriter;

	int    m_oldSeekPos;
	int    _write(const char* buf, int len);
public:
	~CChunkWrite();
	CChunkWrite();
	bool  beginWrite();
	bool  endWrite();

	char* getBuffer();
	int   getBufferLen();


	bool   reserve(int len);
	

	template <typename T> int write(const T& Data)
	{
		return _write( (const char*) &Data,sizeof(T));
	}

	template <typename T> int write(const T* Data, int nObject)
	{
		return _write( (const char*)Data,sizeof(T)*nObject);
	}

	bool   seek(int len , ios::seek_dir);
};


struct sChunkFileHeader_t
{
	char m_MagicChar[4];
	int  m_Version;
	int  m_nChunck;
};

struct sChunk_t
{
	char  m_Name[16];
	DWORD m_Id;
	int   m_Offset;
	int   m_Length;
};

class CChunkFileWriter
{
	sChunkFileHeader_t m_Header;
	vector<sChunk_t>   m_Chunks;
	vector<CChunkWrite*> m_Writers;
	char                 m_FileName[128];
	friend class CChunkWrite;
public:
	CChunkFileWriter()
	{
		m_Header.m_MagicChar[0]=0;
		m_FileName[0]=0;
	}
	bool          open(const char* fileName);
	CChunkWrite* openChunk(const char* chunkName , DWORD chunkId = -1,bool bCreate = true);
	CChunkWrite* openChunk(DWORD chunkId,bool bCreate = true);
	bool          removeChunk(DWORD chunkId);
	bool          removeChunk(const char* chunkName);
	bool          save(char* fileName = NULL);
	bool          close(bool discard = false);
};

class CChunkFileReader
{
	sChunkFileHeader_t   m_Header;
	vector<sChunk_t>     m_Chunks;
	vector<CChunkRead*> m_Readers;
	istream*             m_pStream;
	friend class CChunkRead;
	bool         __read();
public:
	CChunkFileReader()
	{
		m_pStream = NULL;
	}
	bool          open(const char* fileName);
	bool          openBuffer(const char* buf,int len);
	CChunkRead*  openChunk(DWORD chunkId);
	CChunkRead*  openChunk(const char* chunkName);
	void          close();
};

#endif

